import { Menu, message } from 'antd'
import './index.less'
import { useEffect, useState } from 'react'
import { NODE_TYPE_ROOT} from '@/utils/constant.js'
import { NODE_BORDER_COLOR } from '../flow-canvas/nodes'

const CanvasContextmenu = ({ graph, menuConifg, onChangNotes }) => {
  const [menuData, setMenuData] = useState({
    contextStyle: null,
    menuItems: [],
    node: null,
  })

  const showContextMenu = (event, node) => {
    let menuItems = []

    if (node && node.isNode()) {
      if (node.data.typeCode != NODE_TYPE_ROOT) {
        menuItems.push({ label: '复制', key: 'copy' })
      }

      if (node.data.notes) {
        menuItems.push({ label: '反注释', key: 'unnotes' })
      } else {
        menuItems.push({ label: '注释', key: 'notes' })
      }

      if (node.data.typeCode != NODE_TYPE_ROOT) {
        menuItems.push({ label: '删除', key: 'remove' })
      }
    } else if (node && node.isEdge()) {
      menuItems.push({ label: '删除', key: 'remove' })
    } else {
      if (graph.canUndo()) {
        menuItems.push({ label: '撤销', key: 'undo' })
      }

      if (!graph.isClipboardEmpty()) {
        menuItems.push({ label: '粘贴', key: 'paste' })
      }
    }

    menuItems.push(...menuConifg.menuItems(graph, node))

    setMenuData({
      ...menuData,
      contextStyle: menuItems.length == 0 ? null : {
        top: event.clientY,
        left: event.clientX,
        background: '#fff',
      },
      menuItems,
      node,
    })
  }

  const hideContextMenu = (props) => {
    setMenuData({
      ...menuData,
      contextStyle: null,
      menuItems: null,
      ...props
    })
  }

  const menuClickMap = {
    copy: () => {
      graph.copy([menuData.node])
    },
    paste: () => {
      if (graph.isClipboardEmpty()) {
        return
      }

      const { contextStyle } = menuData
      let node = graph.getCellsInClipboard()[0]
      let point = graph.pageToLocal({ x: contextStyle.left, y: contextStyle.top })
      let nodePoint = node.position()
      const offset = {
        dx: point.x - nodePoint.x,
        dy: point.y - nodePoint.y
      }
      graph.paste({offset})
      graph.cleanClipboard()
    },
    remove: () => {
      graph.removeNode(menuData.node.id)
    },
    notes: () => {
      menuData.node.data.notes = true

      switch(menuData.node.shape) {
        case 'custom-rect':
        case 'custom-polygon':
        case 'custom-circle':
        case 'custom-image':
          menuData.node.setAttrs({
            body: {
              stroke: '#ddd',
            }
          })
          break;
      }
      onChangNotes(menuData.node.id, menuData.node.data.notes)
    },
    unnotes: () => {
      menuData.node.data.notes = false
      switch(menuData.node.shape) {
        case 'custom-rect':
        case 'custom-polygon':
        case 'custom-circle':
        case 'custom-image':
          menuData.node.setAttrs({
            body: {
              stroke: NODE_BORDER_COLOR,
            }
          })
          break;
      }
      onChangNotes(menuData.node.id, menuData.node.data.notes)
    },
    undo: () => {
      if (graph.canUndo()) {
        graph.undo()
      }
    }
  }

  const onMenuClick = ({key, domEvent}) => {
    let click = menuClickMap[key]
    let props = {}
    if (click) {
      props = click() || {}
    }

    if (menuConifg.menuClick) {
      let tempProps = menuConifg.menuClick(key, graph, menuData.node, graph.pageToLocal({ x: menuData.contextStyle.left, y: menuData.contextStyle.top }))
      props = {...props, ...tempProps}
    }
    hideContextMenu(props)
  }

  useEffect(() => {
    if (graph) {
      graph.on('node:contextmenu', (event) => {
        showContextMenu(event.e, event.node)
      })

      graph.on('edge:contextmenu', (event) => {
        showContextMenu(event.e, event.edge)
      })

      graph.on('blank:contextmenu', (event) => {
        showContextMenu(event.e)
      })
      graph.on('blank:click', () => {
        hideContextMenu()
      })
      document.addEventListener('click', hideContextMenu)
    }
  }, [graph])

  return <>
    {menuData.contextStyle && (
      <div className="context-menu" style={menuData.contextStyle}>
        <Menu
          items={menuData.menuItems}
          onClick={(event) => onMenuClick(event)}
        />
      </div>
    )}
  </>
}

CanvasContextmenu.displayName = 'CanvasContextmenu'

export default CanvasContextmenu
